from selenium.webdriver.common.by import By

# from hslib.webdriver.remote.webdriver import WebDriver
from qturboframe.lib.webdriver.remote.webdriver import WebDriver
# from hslib.webdriver.remote.webelement import WebElement
from qturboframe.lib.webdriver.remote.webelement import WebElement
from qturboframe.lib.webdriver.exceptions import SeleniumError
from qturboframe.lib.report.log import logger


class BaseElement(object):
    '''
    web组件基础控件类

    :Attributes:
     - driver: 控件所在的当前webdriver对象
     - element: 控件元素webelement对象
     - timeout: 步骤操作的超时时间
    '''

    def __init__(self, element_para, father=None, timeout=5):
        if isinstance(element_para, WebElement):
            self.element = element_para
            self.driver = element_para._parent
            self.timeout = timeout
        elif not isinstance(element_para, dict):
            raise AttributeError('element_para参数类型不正确！')
        else:
            if father is None:
                raise AttributeError('未定位元素，father参数不能为None！')
            if isinstance(father, WebDriver):
                self.driver = father
                self.timeout = timeout
            elif isinstance(father, WebElement):
                self.driver = father._parent
                self.timeout = timeout
            else:
                raise AttributeError('father参数类型不正确！')
            key_list = [By.ID, By.NAME, By.CLASS_NAME, By.TAG_NAME, By.LINK_TEXT,
                        By.PARTIAL_LINK_TEXT,By.CSS_SELECTOR, By.XPATH]
            element_by = ''
            element_value = ''
            assist = ''
            for key, value in element_para.items():
                if key in key_list:
                    element_by = key
                    element_value = value
                else:
                    assist += '{}:{},'.format(key, value)
            assist = assist.strip(',')
            self.element = father.find_element_by_attribute(
                element_by, element_value, assist, self.timeout)


class PublicUI(object):
    '''
    UI界面抽象类

    Attributes:
     - driver: WebDriver
     - timeout: 默认的等待时间
    '''

    def __init__(self, driver:WebDriver):
        self.driver = driver
        self.timeout = 3

    def text_type(self, element_para, father=None):
        if father is None:
            father = self.driver
        return TextType(element_para, father, self.timeout)

    def textarea(self, element_para, father=None):
        if father is None:
            father = self.driver
        return TextArea(element_para, father, self.timeout)

    def select(self, element_para, father=None):
        if father is None:
            father = self.driver
        return Select(element_para, father, self.timeout)

    def table(self, element_para, father=None):
        if father is None:
            father = self.driver
        return Table(element_para, father, self.timeout)


class Table(BaseElement):
    '''
    table表格操作
    '''

    def get_table_title_list(self):
        """
        获取table对象的列名

        :Returns:
            返回table的列名列表

        :Raises:
            SeleniumError: 当前元素不是table
        """
        if self.element.tag_name == 'table':
            # titlestr=self.getelementbyattribute(r'tag name:thead').gettext()
            # titlelist=re.findall(r'[^\n]+',titlestr)
            titlelist = list()
            thead = self.element.find_element_by_attribute('tag name', 'thead', timeout=3)
            trlist = thead.find_elements_by_attribute('tag name', 'tr', timeout=3)
            for tr in trlist:
                try:
                    try:
                        tlist = tr.find_elements_by_attribute('tag name', 'th', timeout=1)
                    except SeleniumError:
                        tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=1)
                except SeleniumError:
                    pass
                else:
                    for t in tlist:
                        text = t.text.strip()
                        titlelist.append(text)
            return titlelist
        else:
            logger.getlogger().debug('元素对象不为table对象，对象类型为：' + self.element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self.element.tag_name)

    def get_table_text_list(self, columns=0, column=0):
        """
        获取table对象的内容

        :Args:
         - columns: table的总列数
         - column: table的第几列

        :Returns:
            返回table的列内容，默认返回table的所有内容

        :Raises:
            SeleniumError: 当前元素不是table
        """
        if self.element.tag_name == 'table':
            #bodystr=self.getelementbyattribute(r'tag name:tbody').gettext()
            #bodylist=re.findall(r'[^\n]+',bodystr)
            bodylist = list()
            tbody = self.element.find_element_by_attribute('tag name', 'tbody', timeout=3)
            trlist = tbody.find_elements_by_attribute('tag name', 'tr', timeout=3)
            for tr in trlist:
                try:
                    try:
                        tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=1)
                    except:
                        tlist = tr.find_elements_by_attribute('tag name', 'th', timeout=1)
                except:
                    pass
                else:
                    for t in tlist:
                        bodylist.append(t)
            textlist = list()
            for i in range(0, len(bodylist)):
                if columns:
                    if (i + 1) % columns == column % columns:
                        text = bodylist[i].text.strip()
                        textlist.append(text)
                else:
                    text = bodylist[i].text.strip()
                    textlist.append(text)
            return textlist
        else:
            logger.getlogger().debug('元素对象不为table对象，对象类型为：' + self.element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self.element.tag_name)

    def get_table_cell_list(self, columns=0, column=0):
        """
        获取table对象的单元格集合

        :Args:
         - columns: table的总列数
         - column: table的第几列

        :Returns:
            返回table的列单元格元素集合，默认返回table的所有单元格元素集合

        :Raises:
            SeleniumError: 当前元素不是table
        """
        if self.element.tag_name == 'table':
            #bodystr=self.getelementbyattribute(r'tag name:tbody').gettext()
            #bodylist=re.findall(r'[^\n]+',bodystr)
            bodylist = list()
            tbody=self.element.find_element_by_attribute('tag name', 'tbody', timeout=3)
            trlist=tbody.find_elements_by_attribute('tag name', 'tr', timeout=3)
            for tr in trlist:
                try:
                    try:
                        tlist = tr.find_elements_by_attribute('tag name', 'td', timeout=1)
                    except:
                        tlist = tr.find_elements_by_attribute('tag name', 'th', timeout=1)
                except:
                    pass
                else:
                    for t in tlist:
                        bodylist.append(t)
            celllist = list()
            for i in range(0, len(bodylist)):
                if columns:
                    if (i + 1) % columns == column % columns:
                        celllist.append(bodylist[i])
                else:
                    celllist.append(bodylist[i])
            return celllist
        else:
            logger.getlogger().debug('元素对象不为table对象，对象类型为：' + self.element.tag_name)
            raise SeleniumError('元素对象不为table对象，对象类型为：' + self.element.tag_name)


class TextType(BaseElement):
    '''文本框操作'''

    def set_value(self, value):
        '''
        文本框填充

        :Args:
         - text: 填充值
        '''
        self.element.focus()
        self.element.clear()
        self.element.send_keys(value)

    def is_default(self, value):
        """
        检查文本框件默认值

        :Args:
         - value: 待检查的值

        :Returns:
            检查匹配返回True，否则返回False
        """
        self.element.focus()
        if self.element.text:
            text = self.element.text
        elif self.element.get_attribute('value'):
            text = self.element.get_attribute('value')
        elif self.element.get_attribute('placeholder'):
            text = self.element.get_attribute('placeholder')
        elif self.element.get_attribute('title'):
            text = self.element.get_attribute('title')
        else:
            text = ''
        if text == value:
            return True
        else:
            logger.getlogger().error('默认值不匹配！')
            return False

    def is_readonly(self):
        '''
        检查文本框是否只读

        :Return:
            返回文本框是否只读
        '''
        self.element.focus()
        return self.element.is_readonly()

    def clear(self):
        '''
        文本框清空
        '''
        self.element.focus()
        self.element.clear()


class TextArea(BaseElement):
    '''多行文本框操作'''

    def set_value(self, text):
        '''
        多行文本框填充

        :Args:
         - text: 填充值
        '''
        self.element.focus()
        self.element.clear()
        self.element.send_keys(text)

    def is_default(self, value):
        """
        检查多行文本框默认值

        :Args:
         - value: 待检查的值

        :Returns:
            检查匹配返回True，否则返回False
        """
        self.element.focus()
        if self.element.text:
            text = self.element.text
        elif self.element.get_attribute('defaultvalue'):
            text = self.element.get_attribute('defaultvalue')
        elif self.element.get_attribute('value'):
            text = self.element.get_attribute('value')
        elif self.element.get_attribute('placeholder'):
            text = self.element.get_attribute('placeholder')
        elif self.element.get_attribute('title'):
            text = self.element.get_attribute('title')
        else:
            text = ''
        if text == value:
            return True
        else:
            logger.getlogger().error('默认值不匹配！')
            return False

    def is_readonly(self):
        '''
        检查多行文本框是否只读

        :Return:
            返回多行文本框是否只读
        '''
        self.element.focus()
        return self.element.is_readonly()

    def clear(self):
        '''
        多行文本框清空
        '''
        self.element.focus()
        self.element.clear()

#
# class Select(BaseElement):
#     '''
#     下拉框操作
#     '''




